/*
 * Copyright 2007 Agile Plugins Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * 	http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.googlecode.agileplugins.monkey;

import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DataKeys;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.util.IncorrectOperationException;

public class AutoBoundaryCompletion extends AnAction {
    private AnAction delegateAction;
    private static final String AUTOBOUNDARY_PREFIX = "au.com.suncorp.easydoc.autoboundary.";

    private String originalClass;
    private String newClass;

    public AutoBoundaryCompletion() {
    }

    public AutoBoundaryCompletion(AnAction delegate) {
        this.delegateAction = delegate;
    }

    public void actionPerformed(AnActionEvent anactionevent) {
        Project project = DataKeys.PROJECT.getData(anactionevent.getDataContext());
        PsiFile psiFile = DataKeys.PSI_FILE.getData(anactionevent.getDataContext());
        if (psiFile != null) {
            String name = psiFile.getName();
            if (name != null) {
                Editor editor = DataKeys.EDITOR.getData(anactionevent.getDataContext());
                if (editor != null) {
                    passthroughActionPerformed(anactionevent, editor, project, psiFile);
                }
            }
        }
        if (delegateAction != null) {
            delegateAction.actionPerformed(anactionevent);
        }
        switchImports(psiFile, project, newClass, originalClass);
    }

    private void passthroughActionPerformed(AnActionEvent anactionevent, Editor editor, Project project, PsiFile psiFile) {
        int offset = editor.getCaretModel().getOffset();
        PsiElement psiElement = psiFile.findElementAt(offset);
        System.out.println("psiElement = " + psiElement);
        PsiElement element = psiElement.getPrevSibling();
        System.out.println("element = " + element + ":" + element.getText());
        PsiElement element1 = element.getPrevSibling();
        System.out.println("element1 = " + element1 + ":" + element1.getText());
        if (element instanceof PsiExpressionStatement) {
            PsiExpressionStatement psiExpressionStatement = (PsiExpressionStatement) element;
            PsiExpression psiExpression = psiExpressionStatement.getExpression();
            if (psiExpression instanceof PsiReferenceExpression) {
                PsiReferenceExpression psiReferenceExpression = (PsiReferenceExpression) psiExpression;
                PsiExpression qualifierExpression = psiReferenceExpression.getQualifierExpression();
                System.out.println("qualifierExpression = " + qualifierExpression);
                PsiType type = qualifierExpression.getType();
                System.out.println("type = " + type);
                if (type.getCanonicalText().startsWith(AUTOBOUNDARY_PREFIX)) {
                    originalClass = type.getCanonicalText();
                    newClass = originalClass.substring(AUTOBOUNDARY_PREFIX.length());
                    switchImports(psiFile, project, originalClass, newClass);
                }
                String name = psiReferenceExpression.getReferenceName();
                System.out.println("name = " + name);
            }
            System.out.println("psiExpression = " + psiExpression);
        }
    }

    private void switchImports(PsiFile psiFile, Project project, String originalImport, String newImport) {
        if (psiFile instanceof PsiJavaFile) {
            PsiJavaFile psiJavaFile = (PsiJavaFile) psiFile;
            PsiImportList psiImportList = psiJavaFile.getImportList();
            final PsiImportStatement originalImportStatement = psiImportList.findSingleClassImportStatement(originalImport);
            PsiManager psiManager = psiFile.getManager();
            final PsiClass aClass = psiManager.findClass(newImport, GlobalSearchScope.allScope(project));
            final PsiElementFactory psiElementFactory = psiManager.getElementFactory();
            final Runnable runnable = new Runnable() {

                public void run() {
                    try {
                        PsiImportStatement psiImportStatement = psiElementFactory.createImportStatement(aClass);
                        originalImportStatement.replace(psiImportStatement);
                    } catch (IncorrectOperationException e) {
                        throw new RuntimeException(e);
                    }
                }
            };
            CommandProcessor.getInstance().executeCommand(project,
                    new Runnable() {
                        public void run() {
                            ApplicationManager.getApplication().runWriteAction(runnable);
                        }
                    }, "Create Autoboundary", null);
        }
    }
}
